home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- fileutil.c
-
- This reusable module contains miscellaneous file management utility routines.
-
- Copyright © 1994-1995, Northwestern University.
-
- ----------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <string.h>
-
- #include "def.h"
- #include "fileutil.h"
- #include "strutil.h"
- #include "memutil.h"
-
-
-
- /*----------------------------------------------------------------------------
- IsEqualFSSpec
-
- Compare two canonical FSSpec records.
-
- Entry: file1 = pointer to first FSSpec record.
- file2 = pointer to second FSSpec record.
-
- Exit: function result = true if the FSSpec records are equal.
- ----------------------------------------------------------------------------*/
-
- Boolean IsEqualFSSpec (FSSpec *file1, FSSpec *file2)
- {
- return
- file1->vRefNum == file2->vRefNum &&
- file1->parID == file2->parID &&
- EqualString(file1->name, file2->name, false, true);
- }
-
-
-
- /*----------------------------------------------------------------------------
- VolNameToVRefNum
-
- Get the volume reference number given a volume name.
-
- Entry: name = volume name.
-
- Exit: function result = error code.
- *vRefNum = volume reference number.
- ----------------------------------------------------------------------------*/
-
- OSErr VolNameToVRefNum (StringPtr name, short *vRefNum)
- {
- HParamBlockRec pb;
- Str31 volNameWithColon;
- short len;
- OSErr err = noErr;
-
- CopyPascalString(volNameWithColon, name);
- len = *volNameWithColon;
- if (volNameWithColon[len] != ':') {
- len = ++(*volNameWithColon);
- volNameWithColon[len] = ':';
- }
- pb.volumeParam.ioNamePtr = volNameWithColon;
- pb.volumeParam.ioVolIndex = -1;
- err = PBHGetVInfoSync(&pb);
- *vRefNum = pb.volumeParam.ioVRefNum;
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- VolNameAndCreationDateToVRefNum
-
- Get the volume reference number given a volume name and creation date.
-
- Entry: name = volume name.
- crDate = creation date.
-
- Exit: function result = error code.
- *vRefNum = volume reference number.
- ----------------------------------------------------------------------------*/
-
- OSErr VolNameAndCreationDateToVRefNum (StringPtr name, long crDate, short *vRefNum)
- {
- HParamBlockRec pb;
- Str31 volName, volNameWithColon;
- short len, ioVolIndex;
- OSErr err = noErr;
-
- for (ioVolIndex = 1; ; ioVolIndex++) {
- pb.volumeParam.ioNamePtr = volName;
- pb.volumeParam.ioVolIndex = ioVolIndex;
- err = PBHGetVInfoSync(&pb);
- if (err != noErr) return err;
- CopyPascalString(volNameWithColon, volName);
- len = *volNameWithColon;
- if (volNameWithColon[len] == ':') {
- (*volName)--;
- } else {
- len = ++(*volNameWithColon);
- volNameWithColon[len] = ':';
- }
- if (EqualString(name, volName, false, true) ||
- EqualString(name, volNameWithColon, false, true))
- {
- if (pb.volumeParam.ioVCrDate == crDate) {
- *vRefNum = pb.volumeParam.ioVRefNum;
- return noErr;
- }
- }
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- CreateTemporaryFile
-
- Create a temporary file.
-
- Entry: prefix = 4 character prefix for file name (e.g., caller's
- creator code).
- creator = file creator.
- type = file type.
-
- Exit: function result = error code.
- *fSpec = FSSpec record for new temporary file.
- ----------------------------------------------------------------------------*/
-
- OSErr CreateTemporaryFile (FSSpec *fSpec, OSType prefix, OSType creator, OSType type)
- {
- OSErr err = noErr;
- long ticks;
-
- err = FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder,
- &fSpec->vRefNum, &fSpec->parID);
- if (err != noErr) return err;
- ticks = TickCount();
- while (true) {
- sprintf((char*)fSpec->name, "%.4s-tmp-%ld", &prefix, ticks);
- c2pstr((char*)fSpec->name);
- err = FSpCreate(fSpec, creator, type, smSystemScript);
- if (err == noErr) return noErr;
- if (err != dupFNErr) return err;
- ticks++;
- }
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DeleteTemporaryFiles
-
- Delete all temporary files.
-
- Entry: prefix = 4 character prefix for file name (e.g., caller's
- creator code).
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr DeleteTemporaryFiles (OSType prefix)
- {
- CInfoPBRec pBlock;
- short vRefNum;
- long dirID;
- OSErr err = noErr;
- Str31 fName;
- short i;
-
- err = FindFolder(kOnSystemDisk, kTemporaryFolderType, kDontCreateFolder,
- &vRefNum, &dirID);
- if (err != noErr) return noErr;
-
- i = 1;
- while (true) {
- pBlock.hFileInfo.ioVRefNum = vRefNum;
- pBlock.hFileInfo.ioDirID = dirID;
- pBlock.hFileInfo.ioNamePtr = fName;
- pBlock.hFileInfo.ioFDirIndex = i;
- err = PBGetCatInfoSync(&pBlock);
- if (err != noErr) return noErr;
- if (((pBlock.hFileInfo.ioFlAttrib >> 4) & 1) == 0) {
- if (*fName >= 4 && strncmp((char*)fName+1, (char*)&prefix, 4) == 0) {
- HDelete(vRefNum, dirID, fName);
- }
- }
- i++;
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetSysVolume
-
- Get the volume reference number of the system volume.
-
- Exit: function result = error code.
- *vRefNum = vol ref num of system volume.
- ----------------------------------------------------------------------------*/
-
- OSErr GetSysVolume (short *vRefNum)
- {
- long dir;
-
- return FindFolder(kOnSystemDisk, kSystemFolderType, false, vRefNum, &dir);
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetIndVolume
-
- Get a volume reference number by volume index.
-
- Entry: index = volume index
-
- Exit: function result = error code.
- *vRefNum = vol ref num of indexed volume.
- ----------------------------------------------------------------------------*/
-
- OSErr GetIndVolume (short index, short *vRefNum)
- {
- ParamBlockRec pb;
- OSErr err = noErr;
-
- pb.volumeParam.ioCompletion = nil;
- pb.volumeParam.ioNamePtr = nil;
- pb.volumeParam.ioVolIndex = index;
-
- err = PBGetVInfoSync(&pb);
-
- *vRefNum = pb.volumeParam.ioVRefNum;
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- MakeLegalFileName
-
- Make a legal file name from a string.
-
- Entry: str = P-format string.
-
- Exit: fileName = P-format file name.
-
- The string is truncated to 31 characters. Any leading period is replaced
- by an underscore (_). Any embedded slashes or colons or CRs are replaced by ' '.
- If the string is empty, the file name "x" is returned.
- ----------------------------------------------------------------------------*/
-
- void MakeLegalFileName (StringPtr str, Str31 fileName)
- {
- short i, len;
-
- len = str[0];
- if (len == 0) {
- CopyPascalString(fileName, "\px");
- return;
- }
- if (len > 31) len = 31;
- fileName[0] = len;
- BlockMoveData(str+1, fileName+1, len);
- if (fileName[1] == '.') fileName[1] = '_';
- for (i = 1; i <= len; i++)
- if (fileName[i] == '/' || fileName[i] == ':' || fileName[i] == CR) fileName[i] = ' ';
- }
-
-
-
- /*----------------------------------------------------------------------------
- OpenDataForkWriteCreateIfMissing
-
- Open the data fork of a file for writing. Create the file if it is missing..
-
- Entry: fSpec = pointer to file spec.
- creator = creator code.
- fileType = file type.
- scriptTag = script code.
- append = true to open for appending data, false to open for
- rewriting data.
-
- Exit: function result = error code.
- *refNum = file reference number.
- *empty = true if file is empty, false if append was requested
- and existing file was not empty.
- ----------------------------------------------------------------------------*/
-
- OSErr OpenDataForkWriteCreateIfMissing (FSSpec *fSpec, OSType creator, OSType fileType,
- ScriptCode scriptTag, Boolean append, short *refNum, Boolean *empty)
- {
- short fRefNum = 0;
- long eof;
- OSErr err = noErr;
-
- *empty = true;
- err = FSpOpenDF(fSpec, fsRdWrPerm, &fRefNum);
- if (err == noErr) {
- if (append) {
- err = GetEOF(fRefNum, &eof);
- if (err != noErr) goto exit;
- if (eof != 0) {
- *empty = false;
- err = SetFPos(fRefNum, fsFromLEOF, 0);
- if (err != noErr) goto exit;
- }
- } else {
- err = SetEOF(fRefNum, 0);
- if (err != noErr) goto exit;
- }
- } else if (err == fnfErr) {
- err = FSpCreate(fSpec, creator, fileType, scriptTag);
- if (err != noErr) goto exit;
- err = FSpOpenDF(fSpec, fsRdWrPerm, &fRefNum);
- if (err != noErr) goto exit;
- } else {
- goto exit;
- }
-
- *refNum = fRefNum;
- return noErr;
-
- exit:
-
- if (fRefNum != 0) MyFSClose(fRefNum, nil);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ValidateSavedFolderAlias
-
- Validate a saved folder alias.
-
- Entry: alias = handle to alias.
-
- Exit: *vRefNum = volume reference number of saved folder.
- *dirID = directory ID of saved folder.
- *valid = true if saved folder valid.
- ----------------------------------------------------------------------------*/
-
- void ValidateSavedFolderAlias (AliasHandle alias, short *vRefNum, long *dirID,
- Boolean *valid)
- {
- OSErr err = noErr;
- FSSpec fSpec;
- Boolean wasChanged;
- CInfoPBRec pb;
-
- *valid = false;
- if (alias == nil) return;
- err = ResolveAlias(nil, alias, &fSpec, &wasChanged);
- if (err != noErr) return;
- pb.dirInfo.ioNamePtr = fSpec.name;
- pb.dirInfo.ioVRefNum = fSpec.vRefNum;
- pb.dirInfo.ioFDirIndex = 0;
- pb.dirInfo.ioDrDirID = fSpec.parID;
- err = PBGetCatInfo(&pb, false);
- if (err != noErr) return;
- if (((pb.dirInfo.ioFlAttrib >> 4) & 1) == 0) return;
- *vRefNum = pb.dirInfo.ioVRefNum;
- *dirID = pb.dirInfo.ioDrDirID;
- *valid = true;
- }
-
-
-
- /*----------------------------------------------------------------------------
- SearchFolderByCreatorAndType
-
- Search a folder for a file by creator and type.
-
- Entry: fSpec = pointer to file spec with vRefNum and parID filled in
- for the folder to be searched.
- creator = creator code.
- fileType = file type.
- *index = starting index in folder. Pass 1 to search the entire
- folder.
-
- Exit: function result = error code.
- = fnfErr if file not found.
- *fSpec = file spec of located file in folder.
- *index = index of located file in folder.
- ----------------------------------------------------------------------------*/
-
- OSErr SearchFolderByCreatorAndType (FSSpec *fSpec, OSType creator, OSType fileType,
- short *index)
- {
- CInfoPBRec pBlock;
- FInfo fndrInfo;
- OSErr err = noErr;
- short i;
-
- i = *index;
- while (true) {
- pBlock.hFileInfo.ioVRefNum = fSpec->vRefNum;
- pBlock.hFileInfo.ioDirID = fSpec->parID;
- pBlock.hFileInfo.ioNamePtr = fSpec->name;
- pBlock.hFileInfo.ioFDirIndex = i;
- err = PBGetCatInfoSync(&pBlock);
- if (err != noErr) return fnfErr;
- if (((pBlock.hFileInfo.ioFlAttrib >> 4) & 1) == 0) {
- err = FSpGetFInfo(fSpec, &fndrInfo);
- if (err != noErr) return err;
- if (fndrInfo.fdCreator == creator && fndrInfo.fdType == fileType) {
- *index = i;
- return noErr;
- }
- }
- i++;
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- FileOrFolderExists
-
- Check to see if a file or folder with a given name exists in a
- directory.
-
- Entry: fSpec = pointer to file spec.
-
- Exit: function result = error code
- = fnfErr if file or folder doesn't exist.
- = noErr if file or folder does exist.
- = something else if error.
- ----------------------------------------------------------------------------*/
-
- OSErr FileOrFolderExists (FSSpec *fSpec)
- {
- OSErr err = noErr;
- CInfoPBRec pBlock;
-
- pBlock.hFileInfo.ioVRefNum = fSpec->vRefNum;
- pBlock.hFileInfo.ioDirID = fSpec->parID;
- pBlock.hFileInfo.ioNamePtr = fSpec->name;
- pBlock.hFileInfo.ioFDirIndex = 0;
- return PBGetCatInfoSync(&pBlock);
- }
-
-
-
- /*----------------------------------------------------------------------------
- MakeFileNameUnique
-
- Generate a unique file name in a directory.
-
- Entry: fSpec = pointer to file spec without suffix.
- suffix = pointer to suffix string, or nil if none.
-
- Exit: function result = error code.
- *fSpec = file spec with unique name.
- ----------------------------------------------------------------------------*/
-
- OSErr MakeFileNameUnique (FSSpec *fSpec, char *suffix)
- {
- short n, stubLen, suffixLen, digitsLen;
- char fileNameStub[32];
- char digitsStr[32];
- char *suffixStr;
- OSErr err = noErr;
-
- CopyPascalString((StringPtr)fileNameStub, fSpec->name);
- p2cstr((StringPtr)fileNameStub);
- suffixStr = suffix == nil ? "" : suffix;
- stubLen = strlen(fileNameStub);
- suffixLen = strlen(suffixStr);
- if (stubLen + suffixLen > 31) {
- stubLen = 31 - suffixLen;
- fileNameStub[stubLen] = 0;
- }
- n = 1;
- sprintf((char*)fSpec->name, "%s%s", fileNameStub, suffixStr);
- c2pstr((char*)fSpec->name);
- while (true) {
- err = FileOrFolderExists(fSpec);
- if (err == fnfErr) return noErr;
- if (err != noErr) return err;
- n++;
- sprintf(digitsStr, ".%d", n);
- digitsLen = strlen(digitsStr);
- if (stubLen + digitsLen + suffixLen > 31) {
- stubLen = 31 - suffixLen - digitsLen;
- fileNameStub[stubLen] = 0;
- }
- sprintf((char*)fSpec->name, "%s%s%s", fileNameStub, digitsStr, suffixStr);
- c2pstr((char*)fSpec->name);
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- MyFSWriteNoCache
-
- Write data to a file with no caching.
-
- Entry: fRefNum = file reference number.
- inOutCount = pointer to number of bytes to write.
- buffer = pointer to data to write.
- giveTime = pointer to function to give time to other
- processes during the write, or nil if none.
-
- Exit: function result = error code.
- *inOutCount = number of bytes written.
- ----------------------------------------------------------------------------*/
-
- OSErr MyFSWriteNoCache (short fRefNum, long *inOutCount, Ptr buffer,
- OSErr (*giveTime)(Boolean))
- {
- ParamBlockRec pBlock;
- OSErr err = noErr;
-
- pBlock.ioParam.ioCompletion = nil;
- pBlock.ioParam.ioResult = 1;
- pBlock.ioParam.ioRefNum = fRefNum;
- pBlock.ioParam.ioBuffer = buffer;
- pBlock.ioParam.ioReqCount = *inOutCount;
- pBlock.ioParam.ioPosMode = 0x20; /* bit 5 set = no cache */
- pBlock.ioParam.ioPosOffset = 0;
- err = PBWriteAsync(&pBlock);
- if (err != noErr) return err;
- do {
- if (err == noErr && giveTime != nil) err = (*giveTime)(true);
- } while (pBlock.ioParam.ioResult > 0);
- *inOutCount = pBlock.ioParam.ioActCount;
- if (err == noErr) err = pBlock.ioParam.ioResult;
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetFileVolRefNum
-
- Get the volume reference number of an open file.
-
- Entry: fRefNum = file reference number.
-
- Exit: function result = error code.
- *vRefNum = volume reference number.
- ----------------------------------------------------------------------------*/
-
- OSErr GetFileVolRefNum (short fRefNum, short *vRefNum)
- {
- FCBPBRec pBlock;
- OSErr err = noErr;
-
- pBlock.ioRefNum = fRefNum;
- pBlock.ioFCBIndx = 0;
- pBlock.ioNamePtr = nil;
- err = PBGetFCBInfoSync(&pBlock);
- if (err != noErr) return err;
- *vRefNum = pBlock.ioFCBVRefNum;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- MyFSClose
-
- Close an open file.
-
- Entry: fRefNum = file reference number.
- giveTime = pointer to function to give time to other
- processes during the close, or nil if none.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr MyFSClose (short fRefNum, OSErr (*giveTime)(Boolean))
- {
- ParamBlockRec pBlock;
- OSErr err = noErr;
- short vRefNum;
-
- err = GetFileVolRefNum(fRefNum, &vRefNum);
- if (err != noErr) return err;
-
- pBlock.ioParam.ioCompletion = nil;
- pBlock.ioParam.ioResult = 1;
- pBlock.ioParam.ioRefNum = fRefNum;
- err = PBCloseAsync(&pBlock);
- if (err != noErr) return err;
- do {
- if (err == noErr && giveTime != nil) err = (*giveTime)(true);
- } while (pBlock.ioParam.ioResult > 0);
- if (err == noErr) err = pBlock.ioParam.ioResult;
- if (err != noErr) return err;
- err = FlushVol(nil, vRefNum);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetLastModDateTime
-
- Get the last mod date and time of a file.
-
- Entry: fSpec = pointer to file spec.
-
- Exit: function result = error code.
- *lastModDateTime = last mod date and time.
- ----------------------------------------------------------------------------*/
-
- OSErr GetLastModDateTime(FSSpec *fSpec, unsigned long *lastModDateTime)
- {
- CInfoPBRec pBlock;
- OSErr err = noErr;
-
- pBlock.hFileInfo.ioNamePtr = fSpec->name;
- pBlock.hFileInfo.ioVRefNum = fSpec->vRefNum;
- pBlock.hFileInfo.ioFDirIndex = 0;
- pBlock.hFileInfo.ioDirID = fSpec->parID;
- err = PBGetCatInfoSync(&pBlock);
- if (err != noErr) return err;
- *lastModDateTime = pBlock.hFileInfo.ioFlMdDat;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- SetLastModDateTime
-
- Set the last mod date and time of a file.
-
- Entry: fSpec = pointer to file spec.
- lastModDateTime = last mod date and time.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr SetLastModDateTime(FSSpec *fSpec, unsigned long lastModDateTime)
- {
- CInfoPBRec pBlock;
- OSErr err = noErr;
-
- pBlock.hFileInfo.ioNamePtr = fSpec->name;
- pBlock.hFileInfo.ioVRefNum = fSpec->vRefNum;
- pBlock.hFileInfo.ioFDirIndex = 0;
- pBlock.hFileInfo.ioDirID = fSpec->parID;
- err = PBGetCatInfoSync(&pBlock);
- if (err != noErr) return err;
- pBlock.hFileInfo.ioNamePtr = fSpec->name;
- pBlock.hFileInfo.ioVRefNum = fSpec->vRefNum;
- pBlock.hFileInfo.ioFDirIndex = 0;
- pBlock.hFileInfo.ioDirID = fSpec->parID;
- pBlock.hFileInfo.ioFlMdDat = lastModDateTime;
- err = PBSetCatInfoSync(&pBlock);
- if (err != noErr) return err;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- CopyOneFork
-
- Copy one fork of a file.
-
- Entry: source = pointer to source file spec.
- dest = pointer to destination file spec.
- resourceFork = true to copy resource fork, false to copy
- data fork.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr CopyOneFork (FSSpec *source, FSSpec *dest, Boolean resourceFork)
- {
- short sourceRefNum = 0;
- short destRefNum = 0;
- long fileSize, len;
- Ptr buf;
- FInfo fInfo;
- OSErr err = noErr;
-
- /* Open source fork. */
-
- if (resourceFork) {
- err = FSpOpenRF(source, fsRdPerm, &sourceRefNum);
- } else {
- err = FSpOpenDF(source, fsRdPerm, &sourceRefNum);
- }
- if (err == fnfErr) return noErr;
- if (err != noErr) goto exit;
- err = GetEOF(sourceRefNum, &fileSize);
- if (err != noErr) goto exit;
-
- /* Open destination fork. Create the fork if it is missing. */
-
- if (resourceFork) {
- err = FSpOpenRF(dest, fsRdWrPerm, &destRefNum);
- } else {
- err = FSpOpenDF(dest, fsRdWrPerm, &destRefNum);
- }
- if (err == fnfErr) {
- err = FSpGetFInfo(source, &fInfo);
- if (err != noErr) goto exit;
- if (resourceFork) {
- FSpCreateResFile(dest, fInfo.fdCreator, fInfo.fdType, smSystemScript);
- err = ResError();
- } else {
- err = FSpCreate(dest, fInfo.fdCreator, fInfo.fdType, smSystemScript);
- }
- if (err != noErr) goto exit;
- if (resourceFork) {
- err = FSpOpenRF(dest, fsRdWrPerm, &destRefNum);
- } else {
- err = FSpOpenDF(dest, fsRdWrPerm, &destRefNum);
- }
- }
- if (err != noErr) goto exit;
- err = SetFPos(destRefNum, fsFromStart, 0);
- if (err != noErr) goto exit;
-
- /* Copy the source fork to the destination fork. */
-
- err = MyNewPtr(1024, &buf);
- if (err != noErr) goto exit;
- while (fileSize > 0) {
- len = fileSize > 1024 ? 1024 : fileSize;
- err = FSRead(sourceRefNum, &len, buf);
- if (err != noErr) goto exit;
- err = FSWrite(destRefNum, &len, buf);
- if (err != noErr) goto exit;
- fileSize -= len;
- }
-
- exit:
-
- if (sourceRefNum != 0) MyFSClose(sourceRefNum, nil);
- if (destRefNum != 0) MyFSClose(destRefNum, nil);
- if (buf != nil) MyDisposePtr(buf);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- CopyFile
-
- Make a copy of a file (both forks).
-
- Entry: source = pointer to source file spec.
- dest = pointer to destination file spec.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr CopyFile (FSSpec *source, FSSpec *dest)
- {
- OSErr err = noErr;
-
- err = CopyOneFork(source, dest, true);
- if (err != noErr) return err;
- return CopyOneFork(source, dest, false);
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetVolList
-
- Get the list of volumes to be scanned.
-
- Exit: function result = error code.
- *volList = handle to list of vol ref nums.
- *numVols = number of volumes in list.
- ----------------------------------------------------------------------------*/
-
- OSErr GetVolList (TVolListHandle *volList, short *numVols)
- {
- TVolListHandle v = nil;
- OSErr err = noErr;
- short n = 0;
- HParamBlockRec pBlock;
- short volIndex = 1;
-
- err = MyNewHandle(0, &v);
- if (err != noErr) goto exit;
-
- while (true) {
- memset(&pBlock, 0, sizeof(pBlock));
- pBlock.volumeParam.ioVolIndex = volIndex;
- err = PBHGetVInfoSync(&pBlock);
- if (err == nsvErr) break;
- if (err != noErr) goto exit;
- n++;
- err = MySetHandleSize(v, n * sizeof(short));
- (*v)[n-1] = pBlock.volumeParam.ioVRefNum;
- volIndex++;
- }
-
- *volList = v;
- *numVols = n;
- return noErr;
-
- exit:
-
- MyDisposeHandle(v);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetFullPath
-
- Get the full path name of a file.
-
- Entry: fSpec = pointer to file spec.
-
- Exit: function result = error code.
- *fullPath = handle to array of Str31 strings listing the
- components of the path in reverse order (file name
- first, volume name last).
- *numComponents = number of components in the path (size of
- fullPath array).
- ----------------------------------------------------------------------------*/
-
- OSErr GetFullPath (FSSpec *fSpec, Str31 ***fullPath, short *numComponents)
- {
- OSErr err = noErr;
- Str31 **h = nil;
- short n = 0;
- CInfoPBRec pBlock;
- Str31 component;
-
- err = MyNewHandle(0, &h);
- if (err != noErr) goto exit;
-
- CopyPascalString(component, fSpec->name);
- pBlock.dirInfo.ioNamePtr = component;
- pBlock.dirInfo.ioVRefNum = fSpec->vRefNum;
- pBlock.dirInfo.ioDrParID = fSpec->parID;
- pBlock.dirInfo.ioFDirIndex = -1;
- while (true) {
- n++;
- err = MySetHandleSize(h, n * sizeof(Str31));
- if (err != noErr) goto exit;
- CopyPascalString((*h)[n-1], component);
- if (pBlock.dirInfo.ioDrParID == fsRtParID) break;
- pBlock.dirInfo.ioDrDirID = pBlock.dirInfo.ioDrParID;
- err = PBGetCatInfoSync(&pBlock);
- if (err != noErr) goto exit;
- }
-
- *fullPath = h;
- *numComponents = n;
- return noErr;
-
- exit:
-
- MyDisposeHandle(h);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- VolSupportsPBCatSearch
-
- Determine whether or not a volume supports the PBCatSearch function.
-
- Entry: vRefNum = vol ref num.
-
- Exit: function result = error code.
- *supportsPBCatSearch = true if PBCatSearch supported.
- ----------------------------------------------------------------------------*/
-
- OSErr VolSupportsPBCatSearch (short vRefNum, Boolean *supportsPBCatSearch)
- {
- OSErr err = noErr;
- HParamBlockRec pBlock;
- GetVolParmsInfoBuffer buf;
-
- pBlock.ioParam.ioNamePtr = nil;
- pBlock.ioParam.ioVRefNum = vRefNum;
- pBlock.ioParam.ioBuffer = (Ptr)&buf;
- pBlock.ioParam.ioReqCount = sizeof(buf);
- err = PBHGetVolParmsSync(&pBlock);
- if (err != noErr) return err;
- *supportsPBCatSearch = (buf.vMAttrib & (1L << bHasCatSearch)) != 0;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- MakeFinderAliasFile
-
- Make a Finder alias file.
-
- Entry: *aliasFSpec = file spec for alias file to be created.
- *targetFSpec = file spec for target object.
-
- Exit: function result = error code.
-
- Warning: Any existing file at "aliasFSpec" is deleted!
- ----------------------------------------------------------------------------*/
-
- OSErr MakeFinderAliasFile (FSSpec *aliasFSpec, FSSpec *targetFSpec)
- {
- AliasHandle alias = nil;
- OSErr err = noErr;
- short refNum = 0;
- Boolean fileCreated = false;
- FInfo fndrInfo;
-
- err = FSpGetFInfo(targetFSpec, &fndrInfo);
- if (err != noErr) return err;
- err = NewAlias(nil, targetFSpec, &alias);
- if (err != noErr) return err;
- FSpDelete(aliasFSpec);
- FSpCreateResFile(aliasFSpec, fndrInfo.fdCreator, 'adrp', smSystemScript);
- err = ResError();
- if (err != noErr) goto exit;
- fileCreated = true;
- refNum = FSpOpenResFile(aliasFSpec, fsRdWrPerm);
- err = ResError();
- if (err != noErr) goto exit;
- AddResource((Handle)alias, 'alis', 0, "\p");
- err = ResError();
- if (err != noErr) goto exit;
- CloseResFile(refNum);
- err = FSpGetFInfo(aliasFSpec, &fndrInfo);
- if (err != noErr) goto exit;
- fndrInfo.fdFlags = 0x8000; /* set bit 15 = alias flag */
- err = FSpSetFInfo(aliasFSpec, &fndrInfo);
- if (err != noErr) goto exit;
- return noErr;
-
- exit:
-
- if (alias != nil) DisposeHandle((Handle)alias);
- if (refNum != 0) CloseResFile(refNum);
- if (fileCreated) FSpDelete(aliasFSpec);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DeleteFolder
-
- Delete a folder.
-
- Entry: fSpec->vRefNum = vol ref num of vol containing folder.
- fSpec->parID = dirID of folder.
- onlyContents = true to delete only the contents of the folder,
- false to delete the contents and the folder itself.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr DeleteFolder (FSSpec *fSpec, Boolean onlyContents)
- {
- OSErr err = noErr;
- CInfoPBRec pBlock;
- FSSpec gSpec;
-
- while (true) {
- pBlock.hFileInfo.ioNamePtr = fSpec->name;
- pBlock.hFileInfo.ioVRefNum = fSpec->vRefNum;
- pBlock.hFileInfo.ioDirID = fSpec->parID;
- pBlock.hFileInfo.ioFDirIndex = 1;
- err = PBGetCatInfoSync(&pBlock);
- if (err == fnfErr) break;
- if (err != noErr) return err;
- if ((pBlock.hFileInfo.ioFlAttrib & ioDirMask) != 0) {
- gSpec.vRefNum = fSpec->vRefNum;
- gSpec.parID = pBlock.dirInfo.ioDrDirID;
- err = DeleteFolder(&gSpec, true);
- if (err != noErr) return err;
- }
- err = FSpDelete(fSpec);
- if (err != noErr) return err;
- }
- if (onlyContents) return noErr;
- pBlock.dirInfo.ioNamePtr = gSpec.name;
- pBlock.dirInfo.ioVRefNum = fSpec->vRefNum;
- pBlock.dirInfo.ioDrDirID = fSpec->parID;
- pBlock.dirInfo.ioFDirIndex = -1;
- err = PBGetCatInfoSync(&pBlock);
- if (err != noErr) return err;
- gSpec.vRefNum = pBlock.dirInfo.ioVRefNum;
- gSpec.parID = pBlock.dirInfo.ioDrParID;
- return FSpDelete(&gSpec);
- }
-